//package io.halo.payment.ctrl;
//
//import cn.hutool.http.HttpUtil;
//import cn.hutool.json.JSONObject;
//import cn.hutool.json.JSONUtil;
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
//import com.wechat.pay.java.core.Config;
//import com.wechat.pay.java.core.RSAAutoCertificateConfig;
//import com.wechat.pay.java.service.payments.jsapi.JsapiService;
//import com.wechat.pay.java.service.payments.jsapi.model.Amount;
//import com.wechat.pay.java.service.payments.jsapi.model.Payer;
//import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
//import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
//import io.halo.payment.channel.wxpay.v2.HaloPaymentWxConfig;
//import io.halo.payment.channel.wxpay.v2.WXPay;
//import io.halo.payment.channel.wxpay.v2.WXPayUtil;
//import io.halo.payment.common.constants.HaloPaymentConstant;
//import io.halo.payment.common.constants.WxConstant;
//import io.halo.payment.common.enums.SignTypeEnum;
//import io.halo.payment.common.utils.R;
//import io.halo.payment.common.validator.ValidatorUtils;
//import io.halo.payment.enums.TradeTypeEnum;
//import io.halo.payment.modules.app.annotation.Login;
//import io.halo.payment.modules.app.form.PayOrderForm;
//import io.halo.payment.modules.app.form.WxLoginForm;
//import io.halo.payment.modules.app.model.HaloPaymentOrder;
//import io.halo.payment.modules.app.model.HaloPaymentUser;
//import io.halo.payment.modules.app.service.HaloPaymentOrderService;
//import io.halo.payment.modules.app.service.HaloPaymentUserService;
//import io.halo.payment.modules.app.utils.JwtUtils;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.RequestBody;
//import org.springframework.web.bind.annotation.RequestHeader;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import javax.annotation.Resource;
//import java.math.BigDecimal;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * 微信登录授权
// *
// * @author austin
// */
//@Slf4j
//@RestController
//@RequestMapping("/pay/wxpay")
//@Api("微信相关接口")
//public class WeiXinController {
//
//    @Value("${halo-pay.application.app-id}")
//    private String appId;
//
//    @Value("${halo-pay.application.app-secret}")
//    private String appSecret;
//
//    @Value("halo-pay.application.mch-key")
//    private String mchKey;
//
//    @Value("halo-pay.application.key-path")
//    private String keyPath;
//
//    @Autowired
//    private JwtUtils jwtUtils;
//
//    /**
//     * 注入微信相关配置
//     */
//    @Autowired
//    private HaloPaymentWxConfig haloPaymentWxConfig;
//
//    @Resource
//    private HaloPaymentUserService haloPaymentUserService;
//    @Resource
//    private HaloPaymentOrderService haloPaymentOrderService;
//
//    /**
//     * 登录，如果用户未存在，注册用户
//     * <p>
//     * 小程序登录调用示例：https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html#%E8%B0%83%E7%94%A8%E7%A4%BA%E4%BE%8B
//     */
//    @PostMapping("login")
//    @ApiOperation("登录")
//    public R login(@RequestBody WxLoginForm form) {
//
//        // 表单校验
//        ValidatorUtils.validateEntity(form);
//        HashMap<String, Object> params = new HashMap<>();
//        params.put("appid", appId);
//        params.put("secret", appSecret);
//        params.put("js_code", form.getCode());
//        params.put("grant_type", "authorization_code");
//        String response = HttpUtil.get(WxConstant.JS_CODE2SESSION, params);
//
//        JSONObject jsonObject = JSONUtil.parseObj(response);
//        // 获取返回用户唯一标识
//        String openId = jsonObject.getStr("openid");
//        if (StringUtils.isBlank(openId)) {
//            return R.error("临时登陆凭证错误");
//        }
//        HaloPaymentUser user = new HaloPaymentUser();
//        user.setOpenId(openId);
//        QueryWrapper<HaloPaymentUser> queryWrapper = new QueryWrapper<>(user);
//        int count = haloPaymentUserService.count(queryWrapper);
//        if (count == 0) {
//            user.setNickname(form.getNickname());
//            user.setAvatarUrl(form.getAvatarUrl());
//            user.setType(2);
//            user.setCreateTime(new Date());
//            haloPaymentUserService.save(user);
//        }
//        user = new HaloPaymentUser();
//        user.setOpenId(openId);
//        queryWrapper = new QueryWrapper<>(user);
//        user = haloPaymentUserService.getOne(queryWrapper);
//
//        // generate token
//        String token = jwtUtils.generateToken(user.getUserId());
//        HashMap<String, Object> resultMap = new HashMap<>();
//        resultMap.put("token", token);
//        resultMap.put("expire", jwtUtils.getExpire());
//
//        return R.ok(resultMap);
//    }
//
//    @Login
//    @PostMapping(value = "/creatMicroAppOrder")
//    @ApiOperation(value = "小程序付款")
//    public R creatMicroAppOrder(@RequestBody PayOrderForm form, @RequestHeader HashMap header) {
//
//        R result = new R();
//
//        ValidatorUtils.validateEntity(form);
//        String token = String.valueOf(header.get("token"));
//        Long userId = Long.valueOf(jwtUtils.getClaimByToken(token).getSubject());
//
//        HaloPaymentUser queryUserEntity = new HaloPaymentUser();
//        queryUserEntity.setUserId(userId);
//        QueryWrapper<HaloPaymentUser> queryWrapper = new QueryWrapper<>(queryUserEntity);
//        HaloPaymentUser user = haloPaymentUserService.getOne(queryWrapper);
//        if (user == null) {
//            return R.error("用户不存在!");
//        }
//        HaloPaymentOrder queryOrderEntity = new HaloPaymentOrder();
//        queryOrderEntity.setId(form.getOrderId());
//        queryOrderEntity.setUserId(user.getUserId());
//        QueryWrapper<HaloPaymentOrder> orderQueryWrapper = new QueryWrapper<>(queryOrderEntity);
//        HaloPaymentOrder order = haloPaymentOrderService.getOne(orderQueryWrapper);
//        if (order == null) {
//            return R.error("该用户订单不存在!");
//        }
//
//        //向微信平台发出请求，创建支付订单，调用统一下单接口：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
//        String amount = order.getAmount().multiply(new BigDecimal("100")).intValue() + "";        //订单总金额：单位分，元转分
//        try {
//            //注入微信相关配置
//            WXPay wxPay = new WXPay(haloPaymentWxConfig);
//            Map<String, String> params = new HashMap<>();
//            params.put(WxConstant.BODY, "订单备注");
//            params.put(WxConstant.NONCE_STR, WXPayUtil.generateNonceStr());          //随机字符串
//            params.put(WxConstant.OUT_TRADE_NO, order.getCode());                    //商户系统内部订单号(这里也就是订单编号)
//            params.put(WxConstant.TOTAL_FEE, amount);                                //订单总金额，单位为分 (字符串类型)
//            params.put(WxConstant.SPBILL_CREATE_IP, "127.0.0.1");                    //终端IP
//            params.put(WxConstant.NOTIFY_URL, "http://127.0.0.1/app/pay/notify");    //异步接收微信支付结果通知的回调地址
//            params.put(WxConstant.TRADE_TYPE, TradeTypeEnum.JSAPI.getTradeType());   //交易类型
//            params.put(WxConstant.OPENID, user.getOpenId());                         //用户授权唯一标识
//
//            //统一下单接口，商户系统需要先调用该接口在微信支付后台生成预支付交易单
//            Map<String, String> response = wxPay.unifiedOrder(params);
//            String flag = response.get("return_code");
//            String prepayId = response.get("prepay_id");
//            if (!WxConstant.FAIL.equals(flag) && StringUtils.isNotBlank(prepayId)) {
//                log.info("prepay_id: {}", prepayId);
//                order.setPrepayId(prepayId);
//                UpdateWrapper<HaloPaymentOrder> updateWrapper = new UpdateWrapper<>();
//                updateWrapper.set("id", order.getId());
//                updateWrapper.set("prepay_id", prepayId);
//                haloPaymentOrderService.update(order, updateWrapper);
//
//                // 生成数字签名等信息返回给前端
//                Map<String, String> data = new HashMap<>(16);
//                String timeStamp = System.currentTimeMillis() + "";
//                String nonceStr = WXPayUtil.generateNonceStr();
//                data.put(WxConstant.APPID, appId);                                //appId
//                data.put(WxConstant.TIMESTAMP, timeStamp);                        //时间戳
//                data.put(WxConstant.NONCE_STR, WXPayUtil.generateNonceStr());     //随机字符串
//                data.put(WxConstant.PACKAGE, prepayId);                           //预支付交易会话标识
//                data.put(WxConstant.SIGN_TYPE, SignTypeEnum.MD5.getType());       //数字签名方式，默认为MD5
//                //生成数字签名
//                String paySign = WXPayUtil.generateSignature(data, mchKey);
//
//                result = R.ok().put(WxConstant.PACKAGE, WxConstant.PREPAY_ID + "=" + prepayId)
//                        .put(WxConstant.TIMESTAMP, timeStamp)
//                        .put(WxConstant.NONCE_STR, nonceStr)
//                        .put(WxConstant.PAY_SIGN, paySign);
//            } else {
//                String errorMsg = String.format("prepay_id获取失败, %s", result.get("return_msg"));
//                result = R.error(errorMsg);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return R.error("微信支付统一下单异常!");
//        }
//        return result;
//    }
//
//    @Login
//    @PostMapping(value = "/creatMicroAppOrderV3")
//    @ApiOperation(value = "小程序付款V3版本")
//    public R creatMicroAppOrderV3(@RequestBody PayOrderForm form, @RequestHeader HashMap header) {
//        ValidatorUtils.validateEntity(form);
//        String token = String.valueOf(header.get("token"));
//        Long userId = Long.valueOf(jwtUtils.getClaimByToken(token).getSubject());
//
//        HaloPaymentUser user = new HaloPaymentUser();
//        user.setUserId(userId);
//        QueryWrapper<HaloPaymentUser> queryWrapper = new QueryWrapper<>(user);
//        HaloPaymentUser one = haloPaymentUserService.getOne(queryWrapper);
//        if (one == null) {
//            return R.error("用户不存在!");
//        }
//        HaloPaymentOrder order = new HaloPaymentOrder();
//        order.setId(form.getOrderId());
//        order.setUserId(one.getUserId());
//        QueryWrapper<HaloPaymentOrder> orderQueryWrapper = new QueryWrapper<>(order);
//        HaloPaymentOrder exist = haloPaymentOrderService.getOne(orderQueryWrapper);
//        if (exist == null) {
//            return R.error("该用户订单不存在!");
//        }
//        String totalAmount = order.getAmount().multiply(new BigDecimal("100")).intValue() + "";
//        // JSAPI下单
//        try {
//            // 第一步：先构建config
//            Config config =
//                    new RSAAutoCertificateConfig.Builder()
//                            .merchantId(HaloPaymentConstant.MERCHANT_ID)
//                            .privateKeyFromPath(HaloPaymentConstant.PRIVATE_KEY_PATH)
//                            .merchantSerialNumber(HaloPaymentConstant.MERCHANT_SERIAL_NUMBER)
//                            .apiV3Key(HaloPaymentConstant.API_V3_KEY)
//                            .build();
//
//            // 第二步：构建service
//            JsapiService service = new JsapiService.Builder().config(config).build();
//            // request.setXxx(value)设置所需要参数
//            PrepayRequest request = new PrepayRequest();
//            Amount amount = new Amount();
//            amount.setTotal(Integer.parseInt(totalAmount));
//            request.setAmount(amount);
//            request.setAppid(appId);
//            request.setMchid(HaloPaymentConstant.MERCHANT_ID);
//            request.setDescription("测试JSAPI下单支付");
//            request.setNotifyUrl("http://127.0.0.1/notify");
//            request.setOutTradeNo(exist.getCode());
//            Payer payer = new Payer();
//            payer.setOpenid(user.getOpenId());
//            request.setPayer(payer);
//            PrepayResponse response = service.prepay(request);
//
//        } catch (Exception e) {
//            e.printStackTrace();
//            return R.error("小程序付款V3版本!");
//        }
//        return R.ok("支付成功!");
//    }
//
//}
